/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "Surface.h"

#include <ppl.h>
#include <向量.h>
#include <文件/file_文件名数据.h>

#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype.h>
#include "底层绘图/底层绘图框架.h"

#include "intern/矢量绘图着色材质.h"
#include "intern/平面几何数据生成.h"

#include "底层绘图/intern/Vulkan/Vulkan框架.h"
#include "core/引擎配置.h"


static FT_Library glibrary = 0;



//S_板载缓存* S_2D画布::m_预设图元顶点     = nullptr;
S_板载缓存* S_2D画布::m_间接绘制图元顶点 = nullptr;


S_板载缓存* S_2D画布::g变换GPU缓存       = nullptr;


S_板载缓存* S_2D画布::g字符GPU缓存       = nullptr;
S_板载缓存* S_2D画布::g行文本变换GPU缓存 = nullptr;
S_板载缓存* S_2D画布::g行文本颜色GPU缓存 = nullptr;

S_板载缓存* S_2D画布::g表格变换GPU缓存   = nullptr;
S_板载缓存* S_2D画布::g表格颜色GPU缓存   = nullptr;

S_板载缓存* S_2D画布::g顶点              = nullptr;
S_板载缓存* S_2D画布::g索引              = nullptr;
S_板载缓存* S_2D画布::g间接              = nullptr;

S_板载缓存* S_2D画布::g凸包变换          = nullptr;
S_板载缓存* S_2D画布::g凸包颜色          = nullptr;
S_板载缓存* S_2D画布::g凸包线属性        = nullptr;

S_板载缓存* S_2D画布::g凸包纹理属性      = nullptr;
S_板载缓存* S_2D画布::g凸包渐变属性      = nullptr;
S_板载缓存* S_2D画布::g凸包渐变控制属性  = nullptr;
S_板载缓存* S_2D画布::g凸包色轮属性      = nullptr;

S_板载缓存* S_2D画布::g图标变换          = nullptr;
S_板载缓存* S_2D画布::g图标颜色          = nullptr;

S_板载缓存* S_2D画布::g纹理变换          = nullptr;
S_板载缓存* S_2D画布::g纹理属性          = nullptr;

S_板载缓存* S_2D画布::g线段              = nullptr;




S_Widget预设图元			S_UI创建环境::m_图元ID;
std::vector< S_2D图元顶点>	S_UI创建环境::m_预设图元顶点;



#ifdef _DEBUG 

#pragma comment(lib, "D:/U/Project/packages/freetype2.2.6.0.1/build/native/lib/x64/Debug/freetype26d.lib")

#else

#pragma comment(lib, "D:/U/Project/packages/freetype2.2.6.0.1/build/native/lib/x64/Release/freetype26.lib")

#endif






uvec2	S_Widget预设图元::m_矩形;
uvec2	S_Widget预设图元::m_左圆角矩形;
uvec2	S_Widget预设图元::m_右圆角矩形;
uvec2	S_Widget预设图元::m_上圆角矩形;
uvec2	S_Widget预设图元::m_下圆角矩形;
uvec2	S_Widget预设图元::m_圆角矩形;
uvec2	S_Widget预设图元::m_左上圆角矩形;
uvec2	S_Widget预设图元::m_右上圆角矩形;
uvec2	S_Widget预设图元::m_圆形;
uvec2	S_Widget预设图元::m_竖向圆角连接线;
uvec2	S_Widget预设图元::m_横向圆角连接线;
uvec2	S_Widget预设图元::m_竖向斜角连接线;
uvec2	S_Widget预设图元::m_横线;
uvec2	S_Widget预设图元::m_竖线;
uvec2	S_Widget预设图元::m_斜线;
uvec2	S_Widget预设图元::m_生成C形左拐角连接线;
uvec2	S_Widget预设图元::m_生成C形右拐角连接线;
uvec2	S_Widget预设图元::m_生成L形下拐角连接线;
uvec2	S_Widget预设图元::m_生成L形上拐角连接线;








S_Surface3D* f_surface_Create(S_设备环境& Ctx3D, const uvec2& size) {
	S_Surface3D* face = (S_Surface3D*)malloc(sizeof(S_Surface3D));
	face->m_交换ID = 0;
	face->m_Ctx = &Ctx3D;

	//auto& ctx = *(((S_绘图配置*)Ctx3D.m_渲染设备)->m_临时设备环境_以后替换层绘图环境);
	std::vector<uint8> data(size.x * size.y * 4);
	//这里创建的纹理 采样数必须为1
	face->m_Color[0] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_U, E_纹理维度类型::e_2D);
	face->m_Color[1] = f_tex_创建帧缓存纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_U, E_纹理维度类型::e_2D);
	face->m_Color[2] = f_tex_创建图像纹理(Ctx3D, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_U, E_纹理维度类型::e_2D);

	f_tex_填充纹理数据(face->m_Color[0], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
	f_tex_填充纹理数据(face->m_Color[1], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
	f_tex_填充纹理数据(face->m_Color[2], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
	//face->m_Depth[0] = f_tex_创建深度纹理(ctx, { size.x, size.y, 1 }, E_MS次数::e_MS_1, E_纹理格式::e_tf_D32F);
	//face->m_Depth[1] = f_tex_创建深度纹理(ctx, { size.x, size.y, 1 }, E_MS次数::e_MS_1, E_纹理格式::e_tf_D32F);
	face->m_帧缓存 = f_创建帧缓存(Ctx3D, size, face->m_Color, 2);
	

	return face;
}

bool f_surface_改变大小(S_Surface3D* face, const uvec2& size) {
	if (size.x <= 0 || size.y <= 0) {
		std::cout << "err: 改变面纹理大小小于最小大小" << std::endl;
	}

	if (face->m_Color[0]->m_Size.x == size.x && face->m_Color[0]->m_Size.y == size.y) {
		return false;
	}


	face->m_交换ID = 0;


	VkDevice 逻辑设备 = (VkDevice)(face->m_Ctx->m_逻辑设备.设备);
	S_绘图设备配置* 绘图设备配置 = (S_绘图设备配置*)(face->m_Ctx->m_逻辑设备.pNext);

	face->m_帧缓存->f_release();


	std::vector<uint8> data(size.x * size.y * 4);
	face->m_Color[0] = f_tex_创建帧缓存纹理(*face->m_Ctx, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_U, E_纹理维度类型::e_2D);
	face->m_Color[1] = f_tex_创建帧缓存纹理(*face->m_Ctx, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_U, E_纹理维度类型::e_2D);
	//face->m_Color[2] = f_tex_创建图像纹理(*face->m_Ctx, { size.x, size.y, 1 }, E_纹理格式::e_tf_RGBA8U_U, E_纹理类型::e_2D);
	//f_tex_修改大小(*face->m_Ctx, face->m_Color[0], size);
	//f_tex_修改大小(*face->m_Ctx, face->m_Color[1], size);
	//f_tex_填充纹理数据(face->m_Color[0], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
	//f_tex_填充纹理数据(face->m_Color[1], (const uint8*)data.data(), sizeof(ubvec4), { size.x, size.y, 1 });
	f_构建帧多重采样缓存(*face->m_Ctx, face->m_帧缓存, size, face->m_Color, 2);


	f_tex_安装纹理采样器(face->m_Color[0], face->m_Smaple);
	f_tex_安装纹理采样器(face->m_Color[1], face->m_Smaple);
	f_tex_安装纹理采样器(face->m_Color[2], face->m_Smaple);

	return true;
}

void f_surface_Release(S_Surface3D* face) {
	face->m_帧缓存->f_release();
}





















S_Widget绘制材质::S_Widget绘制材质(S_设备环境& Ctx, E_MS次数 msCount) {

	m_采样器 = f_tex_创建纹理采样器(Ctx);

	std::cout << "shader file path : " << S_引擎配置::m_UI着色器文件根路径 << std::endl;
	{
		std::cout << "create UI shader 01 : " << S_引擎配置::m_UI着色器文件根路径 << std::endl;
		S_线管创建配置 单色描边图元配置 = {
			{
				{0, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},

			},
			{
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},

			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI单色描边_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI单色_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};

		auto* 单色描边Shader = f_create着色(Ctx, 单色描边图元配置);


		S_线管创建参数 线管参数({ 1024, 576 });
		线管参数.m_绘制方式 = E_绘制方式::e_画连续线;
		线管参数.m_填充模式 = E_填充模式::e_填充面;
		线管参数.m_图元重启 = true;
		线管参数.m_采样 = msCount;
		auto* 线管 = f_create线管(Ctx, *单色描边Shader, 线管参数);

		m_单色描边 = f_create基本材质(单色描边Shader, 线管);
	}



	{
		std::cout << "create UI shader 02" << std::endl;
		S_线管创建配置 渐变描边图元配置 = {
			{
				{0, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{4, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},

			},
			{
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI渐变描边_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI渐变_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};

		auto* 渐变描边Shader = f_create着色(Ctx, 渐变描边图元配置);

		S_线管创建参数 线绘制线管参数({ 1024, 576 });
		线绘制线管参数.m_绘制方式 = E_绘制方式::e_画连续线;
		线绘制线管参数.m_填充模式 = E_填充模式::e_填充线;
		线绘制线管参数.m_图元重启 = true;
		线绘制线管参数.m_采样 = msCount;
		//线绘制线管参数.m_填充模式 = E_填充模式::e_填充面;
		auto* 线绘制线管 = f_create线管(Ctx, *渐变描边Shader, 线绘制线管参数);

		m_渐变描边 = f_create基本材质(渐变描边Shader, 线绘制线管);
	}



	{
		std::cout << "create UI shader 03" << std::endl;
		S_线管创建配置 单色填充图元配置 = {
			{
				{0, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},

			},
			{
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI单色填充_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI单色_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};


		auto* 单色填充Shader = f_create着色(Ctx, 单色填充图元配置);

		S_线管创建参数 线绘制线管参数({ 1024, 576 });
		线绘制线管参数.m_绘制方式 = E_绘制方式::e_三角形带;
		线绘制线管参数.m_填充模式 = E_填充模式::e_填充面;
		线绘制线管参数.m_采样 = msCount;
		//线绘制线管参数.m_填充模式 = E_填充模式::e_填充面;
		auto* 单色填充线管 = f_create线管(Ctx, *单色填充Shader, 线绘制线管参数);

		m_单色填充 = f_create基本材质(单色填充Shader, 单色填充线管);
	}



	{
		std::cout << "create UI shader 04" << std::endl;
		S_线管创建配置 渐变填充图元配置 = {
			{
				{0, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{4, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},

			},
			{
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI渐变填充_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI渐变_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};

		auto* 渐变填充Shader = f_create着色(Ctx, 渐变填充图元配置);

		S_线管创建参数 线绘制线管参数({ 1024, 576 });
		线绘制线管参数.m_绘制方式 = E_绘制方式::e_三角形带;
		线绘制线管参数.m_填充模式 = E_填充模式::e_填充面;
		线绘制线管参数.m_采样 = msCount;
		//线绘制线管参数.m_填充模式 = E_填充模式::e_填充面;
		auto* 渐变填充线管 = f_create线管(Ctx, *渐变填充Shader, 线绘制线管参数);

		m_渐变填充 = f_create基本材质(渐变填充Shader, 渐变填充线管);
	}



	{
		std::cout << "create UI shader 05" << std::endl;
		S_线管创建配置 连接线笔图元配置 = {
			{
				{DEF_BINDING_PROJECT,         E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{DEF_BINDING_WIDGET_PROP,     E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{DEF_BINDING_WIDGET_CurvePoint,   E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
			},
			{
				//{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				//{1,sizeof(vec3),0,E_数据格式::e_F_R32G32B32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "公切圆链接线_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "公切圆链接线_几何阶段.spv", E_着色阶段::e_几何着色},
				{S_引擎配置::m_UI着色器文件根路径 + "公切圆链接线_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};
		

		auto* 连接线笔Shader = f_create着色(Ctx, 连接线笔图元配置);

		S_线管创建参数 线绘制线管参数({ 1024, 576 });
		线绘制线管参数.m_绘制方式 = E_绘制方式::e_画点集;
		线绘制线管参数.m_填充模式 = E_填充模式::e_填充线;
		线绘制线管参数.m_采样 = msCount;
		auto* 连接线笔线管 = f_create线管(Ctx, *连接线笔Shader, 线绘制线管参数);

		m_公切园链接线 = f_create基本材质(连接线笔Shader, 连接线笔线管);
	}


	{
		std::cout << "create UI shader 06" << std::endl;
		S_线管创建配置 连接点笔图元配置 = {
			{
				{0, E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				{4, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},

			},
			{
				//{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				//{1,sizeof(vec3),0,E_数据格式::e_F_R32G32B32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI连接点_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI连接点_几何阶段.spv", E_着色阶段::e_几何着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI连接点_片源阶段段.spv", E_着色阶段::e_像素着色},
			}
		};

		auto* 连接点笔Shader = f_create着色(Ctx, 连接点笔图元配置);

		S_线管创建参数 线绘制线管参数({ 1024, 576 });
		线绘制线管参数.m_绘制方式 = E_绘制方式::e_画点集;
		线绘制线管参数.m_填充模式 = E_填充模式::e_填充点;
		线绘制线管参数.m_采样 = msCount;
		auto* 连接点绘制线管 = f_create线管(Ctx, *连接点笔Shader, 线绘制线管参数);

		m_连接点笔 = f_create基本材质(连接点笔Shader, 连接点绘制线管);
	}


	{
		std::cout << "create UI shader 07" << std::endl;
		S_线管创建配置 临时连接线笔图元配置 = {
			{
				{0, E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				//{6, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
			},
			{
				//{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				//{1,sizeof(vec3),0,E_数据格式::e_F_R32G32B32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI连接点_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI临时连接线_几何阶段.spv", E_着色阶段::e_几何着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI单色_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};


		auto* 临时连接线笔Shader = f_create着色(Ctx, 临时连接线笔图元配置);

		S_线管创建参数 临时线绘制线管参数({ 1024, 576 });
		临时线绘制线管参数.m_绘制方式 = E_绘制方式::e_画点集;
		临时线绘制线管参数.m_填充模式 = E_填充模式::e_填充线;
		临时线绘制线管参数.m_采样 = msCount;
		auto* 临时连接线笔线管 = f_create线管(Ctx, *临时连接线笔Shader, 临时线绘制线管参数);

		m_临时连接线笔 = f_create基本材质(临时连接线笔Shader, 临时连接线笔线管);
	}

	
	

	{
		std::cout << "create UI shader 08" << std::endl;
		S_线管创建配置 文本图元配置 = {
			{
				{DEF_BINDING_PROJECT, E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{DEF_BINDING_WIDGET_PROP, E_着色阶段::e_几何着色, E_板载缓存类型::e_UBO},
				{DEF_BINDING_WIDGET_MATRIX, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				{DEF_BINDING_WIDGET_Color, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				{DEF_BINDING_WIDGET_TextCoordID, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},
				{DEF_BINDING_WIDGET_TextCoord, E_着色阶段::e_几何着色, E_板载缓存类型::e_SSBO},

				{DEF_BINDING_WIDGET_Texture, E_着色阶段::e_像素着色, E_板载缓存类型::e_IMAGE_SAMPLER},
			},
			{
				//{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				//{1,sizeof(vec3),0,E_数据格式::e_F_R32G32B32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI文本_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI文本_几何阶段.spv", E_着色阶段::e_几何着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI文本_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};


		auto* 文本Shader = f_create着色(Ctx, 文本图元配置);

		S_线管创建参数 文本线管参数({ 1024, 576 });
		文本线管参数.m_绘制方式 = E_绘制方式::e_画点集;
		文本线管参数.m_填充模式 = E_填充模式::e_填充点;
		文本线管参数.m_采样 = msCount;
		auto* 文本线管 = f_create线管(Ctx, *文本Shader, 文本线管参数);

		m_文本笔刷 = f_create基本材质(文本Shader, 文本线管);
	}



	{
		std::cout << "create UI shader 09" << std::endl;
		S_线管创建配置 渐变背景纹理填充图元配置 = {
			{
				{0, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{1, E_着色阶段::e_顶点着色, E_板载缓存类型::e_UBO},
				{2, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{3, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},
				{4, E_着色阶段::e_顶点着色, E_板载缓存类型::e_SSBO},

				{10, E_着色阶段::e_像素着色, E_板载缓存类型::e_IMAGE_SAMPLER},
			},
			{
				//{0,sizeof(vec2),0,E_数据格式::e_F_R32G32},
				//{1,sizeof(vec2),0,E_数据格式::e_F_R32G32},
			},
			{
				{S_引擎配置::m_UI着色器文件根路径 + "UI渐变背景纹理填充_顶点阶段.spv", E_着色阶段::e_顶点着色},
				{S_引擎配置::m_UI着色器文件根路径 + "UI渐变背景纹理填充_片源阶段.spv", E_着色阶段::e_像素着色},
			}
		};

		auto* Shader = f_create着色(Ctx, 渐变背景纹理填充图元配置);

		S_线管创建参数 渐变背景纹理填充线管参数({ 1024, 576 });
		渐变背景纹理填充线管参数.m_绘制方式 = E_绘制方式::e_三角形带;
		渐变背景纹理填充线管参数.m_填充模式 = E_填充模式::e_填充面;
		渐变背景纹理填充线管参数.m_采样 = msCount;
		auto* 线管 = f_create线管(Ctx, *Shader, 渐变背景纹理填充线管参数);

		m_渐变背景纹理填充 = f_create基本材质(Shader, 线管);

	}


	std::cout << "create UI shader 10" << std::endl;
	m_单色凸边形填充 = f_初始化凸边形单色填充材质(Ctx, msCount, E_填充模式::e_填充面);
	std::cout << "create UI shader 11" << std::endl;
	m_单色凸边形描边 = f_初始化凸边形单色填充材质(Ctx, msCount, E_填充模式::e_填充线);
	

	std::cout << "create UI shader 12" << std::endl;
	m_边缘阴影			= f_初始化边缘阴影材质(Ctx, msCount);
	std::cout << "create UI shader 13" << std::endl;
	m_条纹填充			= f_初始化条纹材质(Ctx, msCount);
	std::cout << "create UI shader 14" << std::endl;
	m_外部纹理填充		= f_初始化外部纹理材质(Ctx, msCount);
	std::cout << "create UI shader 15" << std::endl;
	m_文本块笔刷		= f_初始化文本块材质(Ctx, msCount);

	std::cout << "create UI shader 16" << std::endl;
	m_单色描边		 = f_初始化线材质(Ctx, msCount);
	std::cout << "create UI shader 17" << std::endl;
	m_刻度线		 = f_初始化刻度线材质(Ctx, msCount);
	std::cout << "create UI shader 18" << std::endl;
	m_网格刻度线	 = f_初始化网格刻度线材质(Ctx, msCount);
	std::cout << "create UI shader 19" << std::endl;
	m_单纹理		 = f_初始化单纹理材质(Ctx, msCount);
	std::cout << "create UI shader 20" << std::endl;
	m_间接单色填充	 = f_初始化间接单色填充材质(Ctx, msCount, E_填充模式::e_填充面);
	std::cout << "create UI shader 21" << std::endl;
	m_间接单色描边	 = f_初始化间接单色填充材质(Ctx, msCount, E_填充模式::e_填充线);
	std::cout << "create UI shader 22" << std::endl;
	m_单色图标笔刷	 = f_初始化间接绘制_单色图标材质(Ctx, msCount);
	std::cout << "create UI shader 23" << std::endl;
	m_纯纹理图标笔刷 = f_初始化间接绘制_图标材质(Ctx, msCount);
	std::cout << "create UI shader 24" << std::endl;
	m_动态线		 = f_初始化_动态线材质(Ctx, msCount);
	std::cout << "create UI shader 25" << std::endl;
	m_曲线点		 = f_初始化_曲线点材质(Ctx, msCount);
	std::cout << "create UI shader 26" << std::endl;
	m_曲线			 = f_初始化_曲线材质(Ctx, msCount, false);
	std::cout << "create UI shader 27" << std::endl;
	m_多曲线		 = f_初始化_曲线材质(Ctx, msCount, true);
	std::cout << "create UI shader 28" << std::endl;
	m_色轮			 = f_初始化_色轮材质(Ctx, msCount);
	std::cout << "create UI shader 29" << std::endl;
	m_渐变			 = f_初始化_渐变材质(Ctx, msCount);
	std::cout << "create UI shader 30" << std::endl;
	m_过程纹理填充	 = f_初始化_过程纹理材质(Ctx, msCount);
	std::cout << "create UI shader 31" << std::endl;
	m_表格线         = f_初始化_表格线材质(Ctx, msCount);
	std::cout << "create UI shader 32" << std::endl;
	m_矢量线         = f_初始化_矢量线材质(Ctx, msCount);

}








S_UI创建环境::S_UI创建环境(S_设备环境& ctx, E_MS次数 msCount) : m_Ctx(ctx) {
	assert(m_预设图元顶点.size());

	if (!glibrary) {
		FT_Error err = FT_Init_FreeType(&glibrary);
		if (err) {
			std::cout << "初始化freetype2失败" << std::endl;
		}
		//载入默认字体纹理, m_Mat(ctx, msCount)
	}

	m_采样数 = msCount;
	m_DPI = 1;

	std::cout << "init global buffer" << std::endl;
	S_2D画布::m_间接绘制图元顶点 = f_buf_create板载缓存(m_Ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO|E_板载缓存类型::e_SSBO , sizeof(mat3X2), 1);

	
	S_2D画布::g变换GPU缓存       = f_buf_create板载缓存(m_Ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO, 0);

	S_2D画布::g字符GPU缓存       = f_buf_create板载缓存(m_Ctx, sizeof(int32), E_板载缓存类型::e_SSBO, 0);
	S_2D画布::g行文本变换GPU缓存 = f_buf_create板载缓存(m_Ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO, 0);
	S_2D画布::g行文本颜色GPU缓存 = f_buf_create板载缓存(m_Ctx, sizeof(uint32), E_板载缓存类型::e_SSBO, 0);

	S_2D画布::g表格变换GPU缓存     = f_buf_create板载缓存(m_Ctx, sizeof(vec2), E_板载缓存类型::e_SSBO, 0);
	S_2D画布::g表格颜色GPU缓存       = f_buf_create板载缓存(m_Ctx, sizeof(uint32), E_板载缓存类型::e_SSBO, 0);

	std::cout << "init VBO buffer" << std::endl;
	S_2D画布::g顶点 = f_buf_create板载缓存(m_Ctx, E_板载缓存类型::e_VBO, E_板载缓存类型::e_VBO|E_板载缓存类型::e_SSBO , sizeof(S_2D图元顶点), 1);
	S_2D画布::g索引 = f_buf_create板载缓存(m_Ctx, sizeof(uint32), E_板载缓存类型::e_INDEX, 0);
	S_2D画布::g间接 = f_buf_create板载缓存(m_Ctx, sizeof(S_VkDrawIndirectCommand), E_板载缓存类型::e_INDIRECT, 1);


	std::cout << "init graph buffer" << std::endl;
	S_2D画布::g凸包变换 = f_buf_create板载缓存(m_Ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO, 0);
	S_2D画布::g凸包颜色 = f_buf_create板载缓存(m_Ctx, sizeof(uint32), E_板载缓存类型::e_SSBO, 0);
	//S_2D画布::g凸包颜色2 = f_buf_create板载缓存(m_Ctx, sizeof(uvec2), E_板载缓存类型::e_SSBO, 0);
	S_2D画布::g凸包线属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_LineProp), E_板载缓存类型::e_SSBO, 0);
	//S_2D画布::g凸包纹理属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_TextueProp), E_板载缓存类型::e_SSBO, 0);

	S_2D画布::g凸包渐变属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_ColorGradient), E_板载缓存类型::e_SSBO, 0);
	S_2D画布::g凸包渐变控制属性 = f_buf_create板载缓存(m_Ctx, sizeof(vec4), E_板载缓存类型::e_SSBO, 0);

	S_2D画布::g凸包色轮属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_ColorTake), E_板载缓存类型::e_SSBO);

	S_2D画布::g图标变换 = f_buf_create板载缓存(m_Ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO);
	S_2D画布::g图标颜色 = f_buf_create板载缓存(m_Ctx, sizeof(uint32), E_板载缓存类型::e_SSBO);

	S_2D画布::g纹理变换 = f_buf_create板载缓存(m_Ctx, sizeof(mat3X2), E_板载缓存类型::e_SSBO);
	S_2D画布::g纹理属性 = f_buf_create板载缓存(m_Ctx, sizeof(S_TextueProp), E_板载缓存类型::e_SSBO, 0);

	S_2D画布::g线段     = f_buf_create板载缓存(m_Ctx, sizeof(S_CurvePoint), E_板载缓存类型::e_SSBO, 0);


	std::cout << "init indirect vert buffer" << std::endl;
	f_buf_fill板载缓存(S_2D画布::m_间接绘制图元顶点, m_预设图元顶点);


	std::cout << "init UI shader" << std::endl;
	m_Mat = new S_Widget绘制材质(ctx, msCount);

	S_2D画布::m_间接绘制图元顶点->f_map();
}

S_UI创建环境::~S_UI创建环境() {
	S_2D画布::m_间接绘制图元顶点->f_unmap();
	
}

void S_UI创建环境::f_初始化预设图元() {
	m_预设图元顶点.clear();
	
	m_图元ID.m_矩形 = f_vg_生成矩形顶点(m_预设图元顶点);
	m_图元ID.m_左圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_左);
	m_图元ID.m_右圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_右);
	m_图元ID.m_上圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_上);
	m_图元ID.m_下圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_下);
	m_图元ID.m_圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_中);
	m_图元ID.m_左上圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_左上);
	m_图元ID.m_右上圆角矩形 = f_vg_生成方向圆角矩形顶点(m_预设图元顶点, E_方向::e_右上);
	m_图元ID.m_竖向圆角连接线 = f_vg_生成圆角连接线顶点(m_预设图元顶点, E_方向::e_纵向);
	m_图元ID.m_横向圆角连接线 = f_vg_生成圆角连接线顶点(m_预设图元顶点, E_方向::e_横向);
	m_图元ID.m_横线 = f_vg_生成直线顶点(m_预设图元顶点, E_方向::e_横向);
	m_图元ID.m_竖线 = f_vg_生成直线顶点(m_预设图元顶点, E_方向::e_纵向);
	m_图元ID.m_斜线 = f_vg_生成直线顶点(m_预设图元顶点, E_方向::e_中);
	m_图元ID.m_生成C形左拐角连接线 = f_vg_生成C形拐角连接线顶点(m_预设图元顶点, E_方向::e_左);
	m_图元ID.m_生成C形左拐角连接线 = f_vg_生成C形拐角连接线顶点(m_预设图元顶点, E_方向::e_左);
	m_图元ID.m_生成L形下拐角连接线 = f_vg_生成L形拐角连接线顶点(m_预设图元顶点, E_方向::e_下);
	m_图元ID.m_生成L形上拐角连接线 = f_vg_生成L形拐角连接线顶点(m_预设图元顶点, E_方向::e_上);
	S_Widget预设图元::m_圆形 = f_vg_生成圆形顶点(m_预设图元顶点);
}

void S_UI创建环境::f_销毁绘图资源() {
	f_buf_release板载缓存(S_2D画布::m_间接绘制图元顶点);

	f_buf_release板载缓存(S_2D画布::g字符GPU缓存);
	f_buf_release板载缓存(S_2D画布::g行文本变换GPU缓存);
	f_buf_release板载缓存(S_2D画布::g行文本颜色GPU缓存);

	f_buf_release板载缓存(S_2D画布::g顶点);
	f_buf_release板载缓存(S_2D画布::g索引);
	f_buf_release板载缓存(S_2D画布::g间接);

	f_buf_release板载缓存(S_2D画布::g凸包变换);
	f_buf_release板载缓存(S_2D画布::g凸包颜色);
	//f_buf_release板载缓存(S_2D画布::g凸包颜色2);
	f_buf_release板载缓存(S_2D画布::g凸包线属性);
	//f_buf_release板载缓存(S_2D画布::g凸包纹理属性);
	f_buf_release板载缓存(S_2D画布::g凸包渐变控制属性);

	f_buf_release板载缓存(S_2D画布::g凸包色轮属性);

	f_buf_release板载缓存(S_2D画布::g图标变换);
	f_buf_release板载缓存(S_2D画布::g图标颜色);

	f_buf_release板载缓存(S_2D画布::g纹理变换);
	f_buf_release板载缓存(S_2D画布::g纹理属性);


	f_buf_release板载缓存(S_2D画布::g线段);
}












S_2D画布::S_2D画布(S_设备环境& ctx) : m_Ctx(ctx) {
	m_绘制推进层 = 0;

	m_父级画布属性 = nullptr;
	
	m_是否重绘 = true;
}

S_2D画布::~S_2D画布() {
	for (auto& s : m_surf)			f_releaseSurface2D(&s);
	for (auto& e : m_扩展GPU参数)	f_buf_release板载缓存(e);
	for (auto& e : m_属性)			f_buf_release板载缓存(e);

	m_surf.clear();
	m_属性.clear();
	m_扩展GPU参数.clear();
	
}


void S_2D画布::f_绘制到屏幕(S_渲染参数& 参数) {
	S_渲染参数 渲染参数 = 参数;

	uint32 num = m_surf.size();
	auto* p = m_surf.data();
	for(uint32 i=0; i<num; ++i){
		auto& 层 = p[i];
		
		if (!层.m_实例数量) {
			continue;
		}


		S_2D绘制GPU全局参数 g{ 参数.m_视图投影矩阵, 层.m_笔刷.m_材质->m_GPU参数set, (S_结构对象指针)&层.m_笔刷 };

		f_setGPU参数布局_2D绘制(层.m_笔刷.m_材质->m_Shader, g);

		渲染参数.m_GPU参数 = 层.m_笔刷.m_材质->m_GPU参数set;
		渲染参数.m_线宽 = 层.m_线宽;

		if (层.m_间接.m_Mem.m_大小) {
			渲染参数.m_间接绘制 = 层.m_间接.m_Buf;
			渲染参数.m_间接 = &层.m_间接;
			
			if (层.m_顶点.m_Mem.m_大小) {
				f_Draw_间接序列(m_Ctx, 层.m_笔刷.m_材质, 层.m_顶点.m_Buf, 渲染参数);
			}
			else {
				f_Draw_间接序列(m_Ctx, 层.m_笔刷.m_材质, m_间接绘制图元顶点, 渲染参数);
			}
			continue;
		}


		渲染参数.m_实例数量 = 层.m_实例数量;
		渲染参数.m_实例偏移 = 层.m_实例偏移;
		
		渲染参数.m_顶点数量 = 层.m_顶点数量;
		渲染参数.m_顶点内存偏移 = 层.m_顶点偏移;

		if (层.m_索引.m_Mem.m_大小) {
			S_索引渲染参数 索引参数;
			索引参数.m_索引 = 层.m_索引.m_Buf;
			索引参数.m_间接 = 0;

			渲染参数.m_索引内存偏移 = 层.m_索引.m_Mem.m_偏移;
			渲染参数.m_索引内存数量 = 层.m_索引.m_Mem.m_大小;

			f_Draw2D_索引三角形(m_Ctx, 层.m_笔刷.m_材质, 层.m_顶点.m_Buf, 索引参数, 渲染参数);
		}
		else {
			if (层.m_顶点.m_Mem.m_大小) {
				f_Draw_序列(m_Ctx, 层.m_笔刷.m_材质, 层.m_顶点.m_Buf, 渲染参数);
			}
			else {
				f_Draw_序列(m_Ctx, 层.m_笔刷.m_材质, m_间接绘制图元顶点, 渲染参数);
			}
		}
	}
}

void S_2D画布::f_清除绘制数据() {
	m_绘制推进层 = 0;
	for (auto& obj : m_surf) {
		f_releaseSurface2D(&obj);
	}
	m_surf.clear();
}

void S_2D画布::f_清除多余绘制面() {
	uint32 num = m_surf.size();
	if (m_绘制推进层 >= num) return;

	auto* p = m_surf.data();
	for (uint32 i = m_绘制推进层; i < num; ++i) {
		f_releaseSurface2D(&m_surf[i]);
	}

	auto a = m_surf.end();
	while (m_surf.size() > m_绘制推进层) {
		m_surf.erase(m_surf.end());
	}
	
}




static S_Rectf f_surface_加载字纹理遮罩(FT_Face& f, wchar_t 编码, uint16 字号, uint32 rowNum, uint8* data) {
	//auto err = FT_Load_Char(f, 编码, FT_LOAD_RENDER);
	auto glyph_index = FT_Get_Char_Index(f, 编码);
	//if(!glyph_index) std::cout << "FT_Get_Char_Index:" << glyph_index << "  = " << wchar_t(编码) << std::endl;
	
	S_Rectf area = {};
	//if (!glyph_index) {
		
	auto err = FT_Load_Glyph(f, glyph_index, FT_LOAD_DEFAULT);
	err = FT_Render_Glyph(f->glyph, FT_RENDER_MODE_NORMAL);
	if (!err) {
		//data.resize(字号 * 字号);
		//auto* p = data.data();
		uint16 高度 = DEF_Min(uint16(字号 - 1), f->glyph->bitmap.rows);
		uint16 宽度 = DEF_Min(uint16(字号 - 1), f->glyph->bitmap.width);

		for (uint16 y = 0; y < 高度; ++y) {
			for (uint16 x = 0; x < 宽度; ++x) {
				//auto& a = data[x + (rowNum * y)];
				uint32 offset = (x + 1) + (rowNum * (y + 1));
				//uint32 offset = (x + 1) + ((y + 1));
				//data[offset] = 128;
				data[offset] = f->glyph->bitmap.buffer[f->glyph->bitmap.width * y + x];
				//f->glyph->bitmap.buffer[f->glyph->bitmap.width * y + x];
			}
		}


		area.左边 = f->glyph->bitmap_left;
		area.顶边 = f->size->metrics.ascender / 64 - f->glyph->bitmap_top;
		//area.顶边 = f->glyph->bitmap_top;
		area.宽度 = f->glyph->bitmap.width;
		area.高度 = f->glyph->bitmap.rows;
	}

	return area; 
}



void f_surface_加载字体(S_UI创建环境& ctx, const S_字体加载参数& 字体参数) {
	FT_Face face;
	auto err = FT_New_Face(glibrary, 字体参数.m_字体名称.c_str(), 0, &face);
	err = FT_Set_Pixel_Sizes(face, 字体参数.m_字号, 字体参数.m_字号);
	err = FT_Select_Charmap(face, FT_ENCODING_UNICODE);
	//err = FT_Select_Charmap(face, FT_ENCODING_GB2312);
	//err = FT_Select_Charmap(face, FT_ENCODING_MS_SYMBOL);
	//err = FT_Select_Charmap(face, FT_ENCODING_NONE);
	//FT_Set_CharMap()
	
	//assert(!err);
	std::string name = 字体参数.m_名称 + "_" + f_整数值转字符串(字体参数.m_字号);
	if (name.empty()) {
		name = 字体参数.m_字体名称 + "_" + f_整数值转字符串(字体参数.m_字号);
	}

	ctx.m_Mat->m_Fonts[name] = S_Font();
	auto& tex = ctx.m_Mat->m_Fonts[name];

	
	tex.m_字号 = 字体参数.m_字号;
	uint64 字体大小 = 字体参数.m_字号 + 2;
	uvec2 纹理大小 = { 8192, 1};

	std::vector<wchar_t>	外部编码;
	std::vector<ivec4>		UV;

	uint64 字符总数量 = 0;
	for (auto& e : 字体参数.m_编码区间) {
		//字符总数量 += e.y - e.x;
		//for (uint32 i = e.x; i < e.y; ++i) {
		//	外部编码.push_back(i);
		//}
		字符总数量 += e;
		外部编码.reserve(字符总数量);
		for (uint32 i = 0; i < e; ++i) {
			外部编码.push_back(i);
		}
	}
	

	uvec2 字符纹理分割 = { 纹理大小.x / 字体大小 };
	字符纹理分割.y = 字符纹理分割.x;
	
	

	纹理大小.x = 字符纹理分割.x * 字体大小;
	纹理大小.y = 字符纹理分割.y * 字体大小;

	uint64 每层纹理中字符个数 = 字符纹理分割.x * 字符纹理分割.y;
	uint64 每层纹理像素数量 = uint64(纹理大小.x * 纹理大小.y );
	uint64 纹理张数 = 字符总数量 / 每层纹理中字符个数 + 1;
	
	std::vector<uint8> data;
	tex.m_区域.resize(字符总数量 + 1);



	//UV数据 第一个存储公共信息 (字符高度)
	UV.resize(uint64(字符总数量 + 1));
	

	auto* p_外部编码 = 外部编码.data();
	auto* p_UV = UV.data();
	auto* p_rect = tex.m_区域.data();

	for (uint32 纹理层ID = 0; 纹理层ID < 纹理张数; ++纹理层ID) {
		std::vector<uint8> tempData(每层纹理像素数量);

		for (int32 y = 0; y < 字符纹理分割.y; ++y) {
			for (uint32 x = 0; x < 字符纹理分割.x; ++x) {
				uint64 X = 字体大小 * x;
				uint64 Y = 纹理大小.x * (字体大小 * y);
				uint64 Z = 每层纹理像素数量 * 纹理层ID;
				

				uint64 i = uint64((每层纹理中字符个数 * 纹理层ID) + (字符纹理分割.x * y) + x);
				uint64 offset = Y + X;

				if (i < 字符总数量) {
					p_rect[i] = f_surface_加载字纹理遮罩(face, p_外部编码[i], 字体大小, 纹理大小.x, &tempData[offset]);
					
					//========= ++i p_UV第一个需要左全局属性 ,所以 p_rect --i =========
					p_UV[i].x = x;
					p_UV[i].y = y;
					p_UV[i].z = 纹理层ID | (uint32(p_rect[i].宽度) << 16);
					p_UV[i].w =  p_rect[i].顶边;
				}
			}
			
		}

		uint64 offset = data.size();
		data.resize(offset + 每层纹理像素数量);
		memcpy(&(data[offset]), tempData.data(), 每层纹理像素数量 * sizeof(uint8));
	}

	UV[0].x = float32(字体大小) / 纹理大小.x;
	UV[0].y = 字体大小;



	uvec3 纹理维度 = { 纹理大小.x , 纹理大小.y , 纹理张数 };
	tex.m_Tex = f_tex_创建图像纹理(ctx.m_Ctx, 纹理维度, E_纹理格式::e_tf_R8U_U, E_纹理维度类型::e_2D_Array);
	f_tex_填充纹理数据(tex.m_Tex, data.data(), sizeof(uint8), 纹理维度);
	f_tex_安装纹理采样器(tex.m_Tex, ctx.m_Mat->m_采样器);
	
	//tex.m_uv偏移 = f_create板载缓存(ctx.m_Ctx, sizeof(mat3X2));
	tex.m_uv偏移 = f_buf_create板载缓存(ctx.m_Ctx, sizeof(ivec4));
	f_buf_fill板载缓存(tex.m_uv偏移, UV, E_板载缓存类型::e_SSBO);
	
	//内部文本ID
	//tex.m_字符外部编码映射内部编码.resize(字符总数量);
	//for (uint32 i = 0; i < 字符总数量; ++i) {
		//tex.m_字符外部编码映射内部编码[p_外部编码[i]] = i;
	//	tex.m_字符外部编码映射内部编码[i] = i;
	//}

	return;
}

uint16 f_surface_get字符串宽度T(const S_Font& font, std::wstring text, float32 gap) {
	//std::atomic<int16> width = 0;
	//Concurrency::parallel_for_each(text.begin(), text.end(), [&](const wchar_t& t) {
	//	width += font.f_get字符宽度(t);
	//});
	int16 width = 0;
	for (auto& t : text) {
		width += font.f_get字符宽度(t);
	}
	return width;
}


uint16 f_surface_get字符串宽度(const S_Font& font, std::wstring text, float32 gap) {
	uint16 width = 0;
	for (auto& t : text) {
		if (t == '\t') width += font.m_字号 * 2 + gap;
		else width += uint16(font.f_get字符宽度(t) + gap);
	}
	return width;
}

uint16 f_surface_get字符串宽度(const S_Font& font, wchar_t text, float32 gap) {
	float32 w = font.f_get字符宽度(text);
	return uint16(w + gap);
}

uint32 f_mesh_gen间接绘制网格属性(S_Mesh* mesh, uint32 num) {
	mesh->m_网格元素属性 = f_buf_alloc(S_Mesh::g_网格属性, num);
	return mesh->m_网格元素属性.m_Mem.m_偏移;
}

uint32 f_mesh_resize间接绘制网格属性(S_Mesh* mesh, uint32 num) {
	f_buf_gresize(mesh->m_网格元素属性, num);
	return mesh->m_网格元素属性.m_Mem.m_偏移;
}

void f_mesh_set间接绘制网格属性(S_Mesh* mesh, const S_MeshTranformProp& prop, uint32 offset) {
	f_buf_物体变换属性_at(mesh->m_网格元素属性, offset) = prop;
}

void f_mesh_set绘制属性(S_Mesh* mesh, const S_MeshDrawProp& prop) {
	if (!mesh->m_绘制属性) {
		mesh->m_绘制属性 = (S_MeshDrawProp*)malloc(sizeof(S_MeshDrawProp));
	}
	(*mesh->m_绘制属性) = prop;
}




struct S_GpuPick {
	Mat44f matrix;
	vec3 s;
	vec3 dir;
};




















